home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 90 / CD Actual 90.iso / Software3D / K-3D / k3d-0.4.2.1 / shaders / k3d_noisysmoke.sl < prev    next >
Encoding:
Text File  |  2004-07-23  |  4.1 KB  |  119 lines

  1. #define snoise(p) (2*noise(p)-1)
  2.  
  3.  
  4. /* Here is where we define the GADD. */
  5. #define GADD(PP,PW,li,g)                                                    \
  6.          if (use_lighting > 0) {                                            \
  7.          li = 0;                                                        \
  8.          illuminance (PW) { li += Cl; }                                 \
  9.      } else { li = 1; }                                                 \
  10.          if (use_noise != 0) {                                              \
  11.              Psmoke = PP*freq;                                              \
  12.              smoke = snoise (Psmoke);                                       \
  13.              /* Optimize: one octave only if not lit */                     \
  14.          if (comp(li,0)+comp(li,1)+comp(li,2) > 0.01) {                 \
  15.                  f=1;                                                       \
  16.                  for (i=1;  i<octaves;  i+=1) {                             \
  17.                       f *= 0.5;  Psmoke *= 2;                               \
  18.                       smoke += f*snoise(Psmoke);                            \
  19.                  }                                                          \
  20.              }                                                              \
  21.              g = density * smoothstep(-1,1,smokevary*smoke);                \
  22.          } else g = density;                                                \
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30. volume k3d_noisysmoke(float density = 60;
  31.               float integstart = 0, integend = 100;
  32.               float stepsize = 0.1; float debug = 0;
  33.               float use_lighting = 1; float use_noise = 1;
  34.               color scatter = 1;    /* for sky, try (1, 2.25, 21) */
  35.               float octaves = 3, freq = 1, smokevary = 1;
  36.               float lightscale = 15;
  37.   )
  38. {
  39. #if 0
  40.   /* PRMan and BMRT used to have I reverse of each other, conflict in spec */
  41.   point Worigin = P + I;
  42.   vector incident = vtransform("shader", -I);
  43. #else
  44.   /* But with BMRT 2.3.6 and later, they're the same... */
  45.   point Worigin = P - I;
  46.   vector incident = vtransform("shader", I);
  47. #endif
  48.   point origin = transform("shader", Worigin);
  49.   vector IN, WIN;
  50.   float d, tau;
  51.   color Cv = 0, Ov = 0;        /* net color & opacity of volume */
  52.   color dC, dO;            /* differential color & opacity */
  53.   float ss, dtau, last_dtau, end;
  54.   float nsteps = 0;        /* record number of integration steps */
  55.   color li, last_li, lighttau;
  56.   point PP, PW, Psmoke;
  57.   color scat;
  58.   float f, smoke;
  59.   uniform float i;
  60.  
  61.   end = min(length(incident), integend) - 0.0001;
  62.  
  63.   /* Integrate forwards from the start point */
  64.   d = integstart + random() * stepsize;
  65.   if(d < end)
  66.     {
  67.       IN = normalize(incident);
  68.       WIN = vtransform("shader", "current", IN);
  69.       PP = origin + d * IN;
  70.       PW = Worigin + d * WIN;
  71.       GADD(PP, PW, li, dtau) ss = min(stepsize, end - d);
  72.       d += ss;
  73.       nsteps += 1;
  74.  
  75.       while(d <= end)
  76.     {
  77.       last_dtau = dtau;
  78.       last_li = li;
  79.       PP = origin + d * IN;
  80.       PW = Worigin + d * WIN;
  81.       GADD(PP, PW, li, dtau)
  82.         /* Our goal now is to find dC and dO, the color and opacity
  83.          * of the portion of the volume covered by this step.
  84.          */
  85.         tau = .5 * ss * (dtau + last_dtau);
  86.       lighttau = .5 * ss * (li * dtau + last_li * last_dtau);
  87.  
  88.       scat = -tau * scatter;
  89.       dO =
  90.         1 - color(exp(comp(scat, 0)), exp(comp(scat, 1)),
  91.               exp(comp(scat, 2)));
  92.       dC = lighttau * dO;
  93.  
  94.       /* Now we adjust Cv/Ov to account for dC and dO */
  95.       Cv += (1 - Ov) * dC;
  96.       Ov += (1 - Ov) * dO;
  97.  
  98.       ss = max(min(ss, end - d), 0.005);
  99.       d += ss;
  100.       nsteps += 1;
  101.     }
  102.     }
  103.  
  104.   /* Ci & Oi are the color (premultiplied by opacity) and opacity of 
  105.    * the background element.
  106.    * Now Cv is the light contributed by the volume itself, and Ov is the
  107.    * opacity of the volume, i.e. (1-Ov)*Ci is the light from the background
  108.    * which makes it through the volume.
  109.    */
  110.   Ci = lightscale * Cv + (1 - Ov) * Ci;
  111.   Oi = Ov + (1 - Ov) * Oi;
  112.  
  113.   if(debug > 0)
  114.     {
  115.       printf("nsteps = %f, t1 = %f, end = %f\n", nsteps, integstart, end);
  116.       printf("   Cv = %c, Ov = %c\n", Cv, Ov);
  117.     }
  118. }
  119.